<template>
  <transition name="fade">
    <button
      v-if="show"
      class="back-to-top"
      :style="{
        width: width,
        height: height,
        borderRadius: borderRadius,
        bottom: bottom,
        right: right,
        ...customStyle,
      }"
      @click="scrollToTop"
      aria-label="回到顶部"
    >
      <slot>{{ content }}</slot>
    </button>
  </transition>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from "vue";

const props = defineProps({
  // 显示阈值（滚动多少像素后显示）
  threshold: {
    type: Number,
    default: 100,
  },
  // 按钮宽度
  width: {
    type: String,
    default: "50px",
  },
  // 按钮高度
  height: {
    type: String,
    default: "50px",
  },
  // 圆角
  borderRadius: {
    type: String,
    default: "50%",
  },
  // 距离底部距离
  bottom: {
    type: String,
    default: "40px",
  },
  // 距离右侧距离
  right: {
    type: String,
    default: "40px",
  },
  // 默认内容（可被插槽覆盖）
  content: {
    type: String,
    default: "回到顶部",
  },
  // 自定义样式对象
  customStyle: {
    type: Object,
    default: () => ({}),
  },
  // 滚动目标元素（默认为window）
  target: {
    type: String,
    default: "",
  },
});

const emit = defineEmits(["click"]);
const show = ref(false);
let targetElement = null;

const handleScroll = () => {
  if (props.target) {
    if (!targetElement) {
      targetElement = document.querySelector(props.target);
      if (!targetElement) return;
    }
    show.value = targetElement.scrollTop > props.threshold;
  } else {
    show.value = window.scrollY > props.threshold;
  }
};

const scrollToTop = () => {
  if (props.target) {
    if (!targetElement) {
      targetElement = document.querySelector(props.target);
      if (!targetElement) return;
    }
    targetElement.scrollTo({
      top: 0,
      behavior: "smooth",
    });
  } else {
    window.scrollTo({
      top: 0,
      behavior: "smooth",
    });
  }
  emit("click");
};

onMounted(() => {
  if (props.target) {
    targetElement = document.querySelector(props.target);
    if (targetElement) {
      targetElement.addEventListener("scroll", handleScroll);
    }
  } else {
    window.addEventListener("scroll", handleScroll);
  }
});

onUnmounted(() => {
  if (props.target && targetElement) {
    targetElement.removeEventListener("scroll", handleScroll);
  } else {
    window.removeEventListener("scroll", handleScroll);
  }
});
</script>

<style scoped>
.back-to-top {
  position: fixed;
  background: #1890ff;
  color: white;
  border: none;
  cursor: pointer;
  font-size: 20px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
  transition: all 0.3s;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 0;
  margin: 0;
  outline: none;
}

.back-to-top:hover {
  background: #40a9ff;
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
}

.back-to-top:active {
  transform: translateY(0);
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s;
}
.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>
